Previous: Hanging Braces, Up: Hanging Braces [Contents][Index]
Syntactic symbols aren’t the only place where you can
customize CC Mode with the lisp equivalent of callback functions.
Remember that actions are usually a list containing
some combination of the symbols before and
after (see Hanging Braces). For
more flexibility, you can instead specify brace
“hanginess” by giving a syntactic symbol an
action function in c-hanging-braces-alist;
this function determines the “hanginess” of a brace,
usually by looking at the code near it.
An action function is called with two arguments: the syntactic
symbol for the brace (e.g., substatement-open), and
the buffer position where the brace has been inserted. Point is
undefined on entry to an action function, but the function must
preserve it (e.g., by using save-excursion). The
return value should be a list containing some combination of
before and after, including neither of
them (i.e., nil).
During the call to the indentation or brace hanging
action function, this variable is bound to the
full syntactic analysis list. This might be, for example,
‘((block-close 73))’. Don’t
ever give c-syntactic-context a value
yourself—this would disrupt the proper functioning of
CC Mode.
This variable is also bound in three other circumstances: (i) when calling a c-hanging-semi&comma-criteria function (see Hanging Semicolons and Commas); (ii) when calling a line-up function (see Custom Line-Up); (iii) when calling a c-special-indent-hook function (see Other Indentation).
As an example, CC Mode itself uses this feature to dynamically determine the hanginess of braces which close “do-while” constructs:
void do_list( int count, char** atleast_one_string )
{
int i=0;
do {
handle_string( atleast_one_string[i] );
i++;
} while( i < count );
}
CC Mode assigns the block-close syntactic symbol
to the brace that closes the do construct, and
normally we’d like the line that follows a
block-close brace to begin on a separate line.
However, with “do-while” constructs, we want the
while clause to follow the closing brace. To do
this, we associate the block-close symbol with the
action function c-snug-do-while:
(defun c-snug-do-while (syntax pos)
"Dynamically calculate brace hanginess for do-while statements."
(save-excursion
(let (langelem)
(if (and (eq syntax 'block-close)
(setq langelem (assq 'block-close c-syntactic-context))
(progn (goto-char (cdr langelem))
(if (= (following-char) ?{)
(forward-sexp -1))
(looking-at "\\<do\\>[^_]")))
'(before)
'(before after)))))
This function simply looks to see if the brace closes a “do-while” clause and if so, returns the list ‘(before)’ indicating that a newline should be inserted before the brace, but not after it. In all other cases, it returns the list ‘(before after)’ so that the brace appears on a line by itself.
Previous: Hanging Braces, Up: Hanging Braces [Contents][Index]